<?php
/**
 * 说明.
 * User: dxk <1024114660@qq.com>
 * Date: 2023/10/16
 */

namespace App\Service\Core\User\User;

use App\Model\Core\Company\CompanyModel;
use App\Model\Core\User\UserModel;
use App\Model\Core\User\UserPatientModel;
use App\Service\Core\Company\CompanyService;
use App\Service\Core\CoreBaseService;
use App\Service\ParamsService;
use App\Traits\SingleInstanceTrait;

class UserService extends CoreBaseService
{
    use SingleInstanceTrait;

    private $UserModel;

    protected function __construct()
    {
        $this->UserModel = UserModel::getInstance();
    }

    /**
     * 注销账户
     * @param int $user_id
     * @param string $operate_by
     * @return array
     */
    public function close(int $user_id, string $operate_by): array
    {
        $conn = $this->UserModel->getConnection();
        $conn->beginTransaction();
        $user = $this->UserModel->getOne($user_id, false, true);
        if (empty($user)) {
            $conn->rollBack();
            return alert_info(1, '账户不存在');
        }
        if ($user['is_close']) {
            $conn->commit();
            return alert_info(0, '账户已注销');
        }
        $res = $this->UserModel->updateOne($user_id, [
                'is_close' => 1,
                'close_at' => date('Y-m-d H:i:s'),
                'close_by' => $operate_by,
                'close_ip' => easy_ip(),
                'mobile' => $user['mobile'] . '-' . time(),
                'username' => $user['username'] . '-' . time(),
            ]
        );
        if ($res === false) {
            $conn->rollBack();
            return alert_info(1, "注销失败，更新用户表失败");
        }
        $company_id = $user['company_id'];
        $company = CompanyModel::getInstance()->getOne($company_id);
        if ($company) {
            CompanyModel::getInstance()->updateOne($company_id, ['user_num' => $company['user_num'] - 1]);
        }
        $conn->commit();
        return alert_info(0, "注销成功");
    }

    /**
     * 检测用户信息是否完善
     * @param int $user_id
     * @return bool
     */
    public function checkUserInfoComplete(int $user_id): bool
    {
        $user = $this->getOne($user_id);
        if (!$user['username'] || !$user['mobile'] || $user['birthday'] == '0000-00-00') {
            return false;
        }
        return true;
    }

    /**
     * 校验用户是否可用
     * @param $user_id
     * @return array
     */
    public function checkUserUsable($user_id): array
    {
        $user_id = (int)$user_id;
        $user = $this->getOne($user_id);
        if (empty($user)) {
            return alert_info(1, '账号不存在');
        }
        if ($user['is_close']) {
            return alert_info(1, '账户已注销');
        }
        if ($user['status'] != ParamsService::STATUS_ENABLE) {
            return alert_info(1, '账号/单位已停用');
        }
        $company_id = $user['company_id'];
        $company = CompanyModel::getInstance()->getOne($company_id);
        if ($company && $company['status'] != ParamsService::STATUS_ENABLE) {
            return alert_info(1, '账号/单位已停用');
        }
        return alert_info(0, 'OK', ['user_info' => $user, 'company' => $company]);
    }

    public function getOne($user_id): array
    {
        $user_id = (int)$user_id;
        return $this->UserModel->getOne($user_id);
    }

    /**
     * 修改用户状态
     * @param $user_id
     * @param $status
     * @param $operate_id
     * @param $operate_by
     * @return array
     */
    public function changeStatus($user_id, $status, $operate_id, $operate_by): array
    {
        $user_id = trim($user_id);
        if (!is_numeric($user_id) || $user_id <= 0) return alert_info(1, '用户ID不能为空');
        $user_id = (int)$user_id;
        $operate_id = (int)$operate_id;
        $operate_by = trim($operate_by);
        if ($operate_id <= 0 || empty($operate_by)) return alert_info(1, '操作人不能为空');
        $conn = UserModel::getInstance()->getConnection();
        $conn->beginTransaction();
        $user_info = UserModel::getInstance()->getOne($user_id, true);
        if (empty($user_info)) {
            $conn->rollBack();
            return alert_info(1, '用户获取失败');
        }
        if ($status == $user_info['status']) {
            $conn->commit();
            return alert_info(0, '状态无需修改');
        }
        $res = UserModel::getInstance()->updateOne($user_id, ['status' => $status, 'updated_by' => $operate_by, 'updated_at' => date('Y-m-d H:i:s')]);
        if ($res === false) {
            $conn->rollBack();
            return alert_info(1, '操作失败:数据库繁忙');
        }
//        if ($user_info['hehuan_token'] && $status == ParamsService::STATUS_DISABLE) {
//            $res = HeHuanService::getInstance()->deleteUserProduct($user_id);
//            if ($res['code'] != 0) {
//                $conn->rollBack();
//                return alert_info(1, '停止用户和缓套餐失败：' . $res['msg']);
//            }
//        }
        $this->addLog('用户管理', '修改用户【' . $user_info['username'] . '】状态【' . $status . '】', $operate_id, $operate_by);
        $conn->commit();
        return alert_info(0, '操作成功');
    }

    /**
     * 删除用户
     * @param $user_id
     * @param $operate_id
     * @param $operate_by
     * @return array
     */
    public function deleteUser($user_id, $operate_id, $operate_by)
    {
        $user_id = trim($user_id);
        if (!is_numeric($user_id) || $user_id <= 0) return alert_info(1, '用户ID不能为空');
        $user_id = (int)$user_id;
        $operate_id = (int)$operate_id;
        $operate_by = trim($operate_by);
        if ($operate_id <= 0 || empty($operate_by)) return alert_info(1, '操作人不能为空');
        $conn = UserModel::getInstance()->getConnection();
        $conn->beginTransaction();
        $user_info = UserModel::getInstance()->getOne($user_id, true);
        if (empty($user_info)) {
            $conn->rollBack();
            return alert_info(1, '用户获取失败');
        }
        $res = UserModel::getInstance()->deleteOne($user_id);
        if ($res === false) {
            $conn->rollBack();
            return alert_info(1, '操作失败:数据库繁忙');
        }
        //删除用户问诊人
        $res = UserPatientModel::getInstance()->deleteByUserId($user_id);
        if ($res === false) {
            $conn->rollBack();
            return alert_info(1, '用户就诊人删除失败');
        }
//        if ($user_info['hehuan_token']) {
//            $res = HeHuanService::getInstance()->deleteUserProduct($user_id);
//            if ($res['code'] != 0) {
//                $conn->rollBack();
//                return alert_info(1, '停止用户和缓套餐失败：' . $res['msg']);
//            }
//        }
        $conn->commit();
        $this->addLog('用户管理', '删除用户【' . $user_info['username'] . ' ID:' . $user_info['id'] . '】', $operate_id, $operate_by);
        CompanyService::getInstance()->changeUserNum($user_info['company_id']);
        return alert_info(0, '操作成功');
    }

    /**
     * 获取用户扩展信息
     * @param $user_info
     * @return array
     */
    public function getExtInfo($user_info)
    {
        if (!is_array($user_info) || empty($user_info)) {
            return [];
        }
        $CompanyService = CompanyService::getInstance();
        $age = getAge($user_info['birthday']);
        $user_info['age'] = $age;
        $user_info['sex_name'] = ParamsService::$sex[$user_info['sex']];
        $company_info = $CompanyService->getOne($user_info['company_id']);
        $user_info['company_name'] = $company_info['company_name'];
        $user_info['status_name'] = ParamsService::$status[$user_info['status']];
        //==20240115 去除就诊人添加限制。去除就诊人的问诊渠道字段，改为根据权益卡上的渠道来判断
        //允许添加就诊人数量信息
//        $allow_add_res = $this->allowAddNum($user_info['user_id']);
//        $user_info['is_allow_add'] = $allow_add_res['data']['is_allow_add'];
//        $user_info['allow_add_num'] = $allow_add_res['data']['allow_add_num'];
//        $user_info['channel_provider'] = $this->getUserChannel($user_info['user_id']);
        return $user_info;
    }

    public function getUserChannel(int $user_id): string
    {
        $user = UserModel::getInstance()->getOne($user_id);
        $company_id = $user['company_id'];
        $company = CompanyModel::getInstance()->getOne($company_id);
        return $company['channel_provider'] ?? ParamsService::CHANNEL_PROVIDER_SELF;
    }

    /**
     * 用户是否允许添加就诊人判断
     * @param $user_id
     * @return array
     * @deprecated
     */
    public function allowAddNum($user_id)
    {
        return alert_info(1, '废弃方法');
        $data = ['is_allow_add' => 0, 'allow_add_num' => 0];
        if (!is_numeric($user_id) || $user_id <= 0) {
            return alert_info(1, '参数错误', $data);
        }
        $UserModel = UserModel::getInstance();
        $user_info = $UserModel->getOne($user_id, false);
        if (empty($user_info)) {
            return alert_info(1, '用户不存在', $data);
        }
        if ($user_info['status'] != ParamsService::STATUS_ENABLE) {
            return alert_info(1, '用户不可用', $data);
        }
        $canadd_patient_user_num = (int)$user_info['canadd_patient_user_num'];
        if ($canadd_patient_user_num <= 0) {
            $data = ['is_allow_add' => 0, 'allow_add_num' => 0];
            return alert_info(0, 'ok', $data);
        }
        $allow_add_num = $canadd_patient_user_num - (int)$user_info['patient_user_num'];
        if ($allow_add_num <= 0) {
            $data = ['is_allow_add' => 0, 'allow_add_num' => 0];
            return alert_info(0, 'ok', $data);
        }
        $data = ['is_allow_add' => 1, 'allow_add_num' => $allow_add_num];
        return alert_info(0, 'ok', $data);
    }

    /**
     * 更新用户就诊人数
     * @param $user_id
     * @return array
     */
    public function changePatientUserNum($user_id)
    {
        $user_id = (int)$user_id;
        $user = $this->getOne($user_id);
        if (empty($user)) {
            return alert_info(1, '用户不存在');
        }
        $patient_user_num = UserPatientModel::getInstance()->getConnectionTable()
            ->where('user_id', $user_id)
            ->getCountForPagination();
        $res = $this->UserModel->getConnectionTable()->where('user_id', $user_id)
            ->update(['patient_user_num' => $patient_user_num]);
        if ($res === false) {
            return alert_info(1, '用户就诊人数更新失败');
        }
        $this->UserModel->clearCache($user);
        return alert_info(0, '操作成功');
    }
}
